SSHGuard
SSHGuard is a lightweight intrusion prevention tool that blocks IP addresses exhibiting suspicious behavior, typically repeated authentication failures against SSH. Like Fail2Ban, it reacts to log activity and applies temporary firewall blocks. SSHGuard is often chosen when you want a simpler, lower-maintenance solution with fewer moving parts, especially on servers where you primarily need SSH brute-force suppression.
Background and history
As SSH became the default remote administration method for Linux servers, internet-exposed hosts began receiving continuous brute-force attempts. Early defenses relied on manual firewall rules and SSH daemon throttling. Tools like SSHGuard emerged to automatically detect repeated failures and blacklist abusive sources using the host firewall. Over time, SSHGuard expanded to support multiple log formats and integration with different firewall backends.
Adoption and where it’s commonly used
SSHGuard is commonly used on:
- VPS and cloud servers with public SSH
- Minimalist setups that prefer simple tooling
- Environments where Fail2Ban feels too heavy for the required scope
- Systems that already have a firewall (UFW, iptables/nftables, pf on BSD)
Maintained by
- Maintained by the SSHGuard project community.
Best when to use
- You primarily need SSH brute-force suppression.
- You want a small, simple service with minimal configuration.
- You prefer a tool that reacts automatically without maintaining multiple jails.
- You want quick protection on a small VPS without extra dependencies.
Not suitable when
- You need multi-service protection (web auth, mail, application logs) with service-specific policies.
- You need complex filters, custom regex, or many distinct “jails” like Fail2Ban supports.
- You need centralized reporting and fleet policy management.
- Your environment requires strict allowlisting logic and custom ban actions per service.
Compatibility notes
-
Package availability varies by distribution.
-
Firewall integration differs based on OS and firewall stack.
-
Log sources differ:
- Some systems rely on
/var/log/auth.log - Others rely on journald
- Some systems rely on
-
SSHGuard is commonly used on BSD systems as well; this page focuses on Linux usage patterns.
Any automated banning tool can block your own IP if you mistype credentials or trigger repeated failures during testing. Ensure you have console access or an allowlist strategy before enabling it on production servers.
Concepts and how it works
SSHGuard monitors authentication logs and identifies IPs that exceed a failure threshold. When triggered, it blocks the source IP using a firewall backend for a fixed period. After the block duration expires, the IP is released automatically unless it re-triggers.
Installation
Debian/Ubuntu
sudo apt update
sudo apt install -y sshguard
RHEL/Fedora/Rocky/AlmaLinux
SSHGuard availability depends on repositories. If available:
sudo dnf install -y sshguard
If not available in your base repos, prefer Fail2Ban for consistency across hosts.
Service management
Enable and start:
sudo systemctl enable --now sshguard
Check status:
systemctl status sshguard --no-pager
View recent logs:
journalctl -u sshguard -n 200 --no-pager
Firewall integration
SSHGuard typically integrates with the host firewall automatically based on distro packaging defaults. Validation should be performed on your host to confirm blocks actually apply.
Verify SSH is being monitored
Generate a few failed SSH logins from a different IP, then check SSHGuard logs:
journalctl -u sshguard -n 200 --no-pager
Verify blocks exist in firewall rules
UFW
If you use UFW, verify active rules:
sudo ufw status numbered
nftables
sudo nft list ruleset | less
iptables (legacy)
sudo iptables -S | less
SSHGuard’s blocking mechanism is packaging- and OS-dependent. If you require predictable behavior across mixed distributions, standardize on one tool (often Fail2Ban) and one firewall stack.
Configuration
SSHGuard configuration can differ by distro. The common approach is to:
- confirm which log source it reads (files vs journald)
- confirm which firewall backend it writes to
- adjust thresholds and ban times where supported
Locate configuration files
Read-only discovery:
dpkg -L sshguard 2>/dev/null | grep -E 'sshguard\.conf|/etc/' || true
rpm -ql sshguard 2>/dev/null | grep -E 'sshguard\.conf|/etc/' || true
Common locations you may see:
/etc/sshguard.conf/etc/sshguard/sshguard.conf- systemd unit overrides or environment files
Typical tunables (names vary)
| Setting | Meaning |
|---|---|
| - | - |
| Threshold | How many failures trigger a block |
| Block time | How long an IP remains blocked |
| Whitelist | IPs/subnets excluded from blocking |
| Log source | Which log file or journal source to monitor |
Keep allowlists minimal and limited to trusted admin IPs (office/VPN). Avoid large CIDR allowlists unless you fully understand the security tradeoff.
Practical use cases
Use case: Minimal SSH brute-force suppression on a small VPS
- Install and enable SSHGuard.
- Confirm SSH is accessible and logs are visible.
- Trigger a few failed logins from a different IP (not your admin IP).
- Validate a block is applied and expires as expected.
Operational checks:
systemctl status sshguard --no-pager
journalctl -u sshguard -n 200 --no-pager
Use case: Combine with SSH hardening
SSHGuard works best when paired with:
- key-based SSH auth
- disabling root SSH login
- restricting SSH by IP where feasible
- changing SSH port only if you can manage operational complexity safely
Troubleshooting
SSHGuard runs but never blocks
Likely causes:
- Not reading the correct logs
- Firewall backend not applying rules
- Logs are handled by journald but SSHGuard expects file logs (or vice versa)
Checks:
journalctl -u sshguard -n 200 --no-pager
journalctl -u ssh -n 200 --no-pager 2>/dev/null || journalctl -u sshd -n 200 --no-pager
If SSH authentication logs are present but SSHGuard shows nothing, revisit configuration and packaging defaults.
You got blocked (self-ban)
Recovery requires server access:
- Use provider console access if SSH is blocked.
- Stop SSHGuard temporarily and remove the block using your firewall tooling.
Example emergency stop:
sudo systemctl stop sshguard
Then remove the relevant firewall rule (method depends on UFW/nftables/iptables).
Always maintain a recovery path (provider console/serial) before enabling automated blocking on production SSH endpoints.
Security notes
-
SSHGuard reduces brute-force noise but does not replace:
- SSH keys
- disabling root login
- strong access control and patching
- perimeter protections (provider firewall, allowlists)
-
Treat automated blocking as one layer in a defense-in-depth strategy.
Quick reference
| Goal | Command |
|---|---|
| -- | - |
| Install (Debian/Ubuntu) | sudo apt install -y sshguard |
| Enable and start | sudo systemctl enable --now sshguard |
| Status | systemctl status sshguard --no-pager |
| Logs | journalctl -u sshguard -n 200 --no-pager |
| Check SSH logs | journalctl -u ssh -n 200 --no-pager || journalctl -u sshd -n 200 --no-pager |
| UFW rules | sudo ufw status numbered |